home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume19 / fbm / part05 < prev    next >
Encoding:
Internet Message Format  |  1989-06-08  |  56.6 KB

  1. Subject:  v19i051:  FBM, image manipulation library, Part05/08
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Michael.Mauldin@NL.CS.CMU.EDU
  7. Posting-number: Volume 19, Issue 51
  8. Archive-name: fbm/part05
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 5 (of 8)."
  17. # Contents:  fbext.c fbps.c flclr.c fledge.c flklnr.c flsun.c pbm2ps.c
  18. # Wrapped by rsalz@fig.bbn.com on Fri Jun  9 08:38:26 1989
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'fbext.c' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'fbext.c'\"
  22. else
  23. echo shar: Extracting \"'fbext.c'\" \(6337 characters\)
  24. sed "s/^X//" >'fbext.c' <<'END_OF_FILE'
  25. X/*****************************************************************
  26. X * fbext.c: FBM Library 0.94 (Beta test) 20-May-89  Michael Mauldin
  27. X *
  28. X * Copyright (C) 1989 by Michael Mauldin.  Permission is granted to
  29. X * use this file in whole or in part provided that you do not sell it
  30. X * for profit and that this copyright notice is retained unchanged.
  31. X *
  32. X * fbext.c: 
  33. X *
  34. X * USAGE
  35. X *    % fbext [ -w<width> -h<height> -W<maxwidth> -H<maxheight>
  36. X *         -a<aspect> -t'title' -c'credits' ]
  37. X *           [ x y width height ] < foo.fbm > bar.fbm
  38. X *
  39. X * EDITLOG
  40. X *    LastEditDate = Sat May 20 19:03:55 1989 - Michael Mauldin
  41. X *    LastFileName = /usr2/mlm/src/misc/fbm/fbext.c
  42. X *
  43. X * HISTORY
  44. X * 20-May-89  Michael Mauldin (mlm) at Carnegie Mellon University
  45. X *    Bug fix from Dave Cohrs <dave@cs.wisc.edu>
  46. X *
  47. X * 20-Apr-89  Michael Mauldin (mlm) at Carnegie Mellon University
  48. X *    Beta release (version 0.91) mlm@cs.cmu.edu
  49. X *
  50. X * 22-Aug-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  51. X *    Created.
  52. X *****************************************************************/
  53. X
  54. X# include <stdio.h>
  55. X# include <math.h>
  56. X# include "fbm.h"
  57. X
  58. Xint allowrot = 0;
  59. X
  60. X# define USAGE \
  61. X"Usage:    fbext [ -w<width> -h<height> ] [ -R ]\n\
  62. X          [ -W<maxwdith> -H<maxheight> -s<size> ]\n\
  63. X          [ -a<aspect> -t'title' -c'credits' ] [ -<type> ]\n\
  64. X          [ x y [ width height ] ]    < image > image"
  65. X
  66. X#ifndef lint
  67. Xstatic char *fbmid =
  68. X    "$FBM fbext.c <0.94> 20-May-89  (C) 1989 by Michael Mauldin$";
  69. X#endif
  70. X
  71. Xmain (argc, argv)
  72. Xchar *argv[];
  73. X{ int xo = -1, yo = -1, w = -1, h = -1, ow = -1, oh = -1, size = -1;
  74. X  int mh = -1, mw = -1;
  75. X  double aspect = -1.0;
  76. X  char title[FBM_MAX_TITLE], credits[FBM_MAX_TITLE];
  77. X  FBM input, rotated, output, *image = &input;
  78. X  int outtype = FMT_FBM;
  79. X
  80. X  /* Clear the memory pointers so alloc_fbm won't be confused */
  81. X  input.cm  = input.bm  = (unsigned char *) NULL;
  82. X  rotated.cm = rotated.bm = (unsigned char *) NULL;
  83. X  output.cm = output.bm = (unsigned char *) NULL;
  84. X
  85. X  title[0] = '\0';
  86. X  credits[0] = '\0';
  87. X
  88. X  /* Get the options */
  89. X  while (--argc > 0 && (*++argv)[0] == '-')
  90. X  { while (*++(*argv))
  91. X    { switch (**argv)
  92. X      { case 't':    strcpy (title, *argv+1); CLRARG; break;
  93. X    case 'c':    strcpy (credits, *argv+1); CLRARG; break;
  94. X    case 'a':    aspect = atof (*argv+1); SKIPARG; break;
  95. X    case 'w':    ow = atoi (*argv+1); SKIPARG; break;
  96. X    case 'h':    oh = atoi (*argv+1); SKIPARG; break;
  97. X    case 'W':    mw = atoi (*argv+1); SKIPARG; break;
  98. X    case 'H':    mh = atoi (*argv+1); SKIPARG; break;
  99. X    case 'R':    allowrot++; break;
  100. X    case 's':    size = atoi (*argv+1); SKIPARG; break;
  101. X    case 'A':    outtype = FMT_ATK; break;
  102. X    case 'B':    outtype = FMT_FACE; break;
  103. X    case 'F':    outtype = FMT_FBM; break;
  104. X    case 'G':    outtype = FMT_GIF; break;
  105. X    case 'I':    outtype = FMT_IFF; break;
  106. X    case 'L':    outtype = FMT_LEAF; break;
  107. X    case 'M':    outtype = FMT_MCP; break;
  108. X    case 'P':    outtype = FMT_PBM; break;
  109. X    case 'S':    outtype = FMT_SUN; break;
  110. X    case 'T':    outtype = FMT_TIFF; break;
  111. X    case 'X':    outtype = FMT_X11; break;
  112. X    case 'Z':    outtype = FMT_PCX; break;
  113. X    default:    fprintf (stderr, "%s\n", USAGE);
  114. X            exit (1);
  115. X      }
  116. X    }
  117. X  }
  118. X
  119. X
  120. X  if (read_bitmap (&input, (char *) NULL))
  121. X  {
  122. X    if (image->hdr.physbits != 8)
  123. X    { fprintf (stderr,
  124. X           "Can't handle images with %d bits and %d physbits per pixel\n",
  125. X           image->hdr.bits, image->hdr.physbits);
  126. X      exit (1);
  127. X    }
  128. X
  129. X    /* Get arguments */
  130. X    if (argc > 0)    xo    = atoi (argv[0]);
  131. X    if (xo < 0)        xo    = 0;
  132. X
  133. X    if (argc > 1)    yo    = atoi (argv[1]);
  134. X    if (yo < 0)        yo    = 0;
  135. X
  136. X    if (argc > 2)    w    = atoi (argv[2]);
  137. X    if (w < 0)        w    = image->hdr.cols - xo;
  138. X
  139. X    if (argc > 3)    h    = atoi (argv[3]);
  140. X    if (h < 0)        h    = image->hdr.rows - yo;
  141. X
  142. X    if (argc > 4)    ow    = atoi (argv[4]);
  143. X
  144. X    if (argc > 5)    aspect = atof (argv[5]);
  145. X    
  146. X    /* If 'allowrot' is on, rotate image if its fits better */
  147. X    if (allowrot && mh > 0 && mw > 0)
  148. X    { int inhoriz=0, outhoriz=0;
  149. X    
  150. X      if (aspect < 0.0) aspect = 1.0;
  151. X    
  152. X      if (image->hdr.cols >= (image->hdr.aspect * image->hdr.rows)) inhoriz++;
  153. X      if (mw >= (aspect * mh))                     outhoriz++;
  154. X      
  155. X      if (inhoriz != outhoriz)
  156. X      { if (rotate_fbm (image, &rotated, 90))
  157. X        { free (image);
  158. X      image = &rotated;
  159. X      
  160. X      fprintf (stderr, "Rotating [%dx%d] image for better fit [%dx%d]\n",
  161. X           image->hdr.rows, image->hdr.cols, mw, mh);
  162. X    }
  163. X      }
  164. X      else
  165. X      { exit (1); }
  166. X    }
  167. X
  168. X    /* If max number of pixels specified, calculate width and height */
  169. X    if (size > 0)
  170. X    { if (ow > 0 || oh > 0)
  171. X      { fprintf (stderr,
  172. X      "fbext: error, can only specify one of size and width,height\n");
  173. X    exit (1);
  174. X      }
  175. X      
  176. X      aspect = 1.0;
  177. X
  178. X      ow = sqrt ((double) size * w / (h * image->hdr.aspect));
  179. X      ow &= ~7;            /* Make width multiple of 8 */
  180. X      oh = ow * image->hdr.aspect * h / w;
  181. X    }
  182. X
  183. X    /* If given width and height, must determine output aspect */
  184. X    if (aspect <= 0.0)
  185. X    { if (ow > 0 && oh > 0)
  186. X      { aspect = image->hdr.aspect * ow * h / (oh * w); }
  187. X      else
  188. X      { aspect = image->hdr.aspect; }
  189. X    }
  190. X
  191. X    /* If given only maximum sizes, assume largest width */
  192. X    if (ow <= 0 && oh <= 0)
  193. X    { if (mw > 0)    ow = mw;
  194. X      else if (mh > 0)    oh = mh;
  195. X    }
  196. X
  197. X    /*
  198. X     * If given one of width or height, calculate the other.
  199. X     * If given only aspect ratio, inflate the smaller dimension
  200. X     */
  201. X
  202. X    if (ow > 0 && oh > 0)
  203. X    { /* Nothing to pick */ }
  204. X    else if (ow <= 0 && oh > 0)
  205. X    { ow = ((double) oh + 0.5) * (aspect / image->hdr.aspect) * w / h; }
  206. X    else if (ow > 0 && oh <= 0)
  207. X    { oh = ((double) ow + 0.5) * (image->hdr.aspect / aspect) * h / w; }
  208. X    else if (aspect != image->hdr.aspect)
  209. X    { if (aspect > image->hdr.aspect)
  210. X      { oh = h;
  211. X        ow = ((double) oh + 0.5) * (aspect / image->hdr.aspect) * w / h;
  212. X      }
  213. X      else
  214. X      { ow = w;
  215. X        oh = ((double) ow + 0.5) * (input.hdr.aspect / aspect) * h / w;
  216. X      }
  217. X    }
  218. X    else
  219. X    { ow = w; oh = h; }
  220. X     
  221. X    /* If either dimension exceeds given maximums, shrink the image to fit */
  222. X    if (mh > 0 && oh > mh)
  223. X    { ow = ow * mh / oh; oh = mh; }
  224. X
  225. X    /* Now extract the specified rectangle and write it out */
  226. X    if (mw > 0 && ow > mw)
  227. X    { oh = oh * mw / ow; ow = mw; }
  228. X
  229. X    if (extract_fbm (&input, &output, xo, yo, w, h, ow, oh,
  230. X             title[0] ? title : NULL,
  231. X             credits[0] ? credits : NULL))
  232. X    { if (write_bitmap (&output, stdout, outtype)) exit (0); }
  233. X  }
  234. X  
  235. X  exit (1);
  236. X}
  237. END_OF_FILE
  238. if test 6337 -ne `wc -c <'fbext.c'`; then
  239.     echo shar: \"'fbext.c'\" unpacked with wrong size!
  240. fi
  241. # end of 'fbext.c'
  242. fi
  243. if test -f 'fbps.c' -a "${1}" != "-c" ; then 
  244.   echo shar: Will not clobber existing file \"'fbps.c'\"
  245. else
  246. echo shar: Extracting \"'fbps.c'\" \(7399 characters\)
  247. sed "s/^X//" >'fbps.c' <<'END_OF_FILE'
  248. X/****************************************************************
  249. X * fbps.c: FBM Library 0.92 (Beta test) 27-Apr-89  Michael Mauldin
  250. X *
  251. X * Copyright (C) 1989 by Michael Mauldin.  Permission is granted to
  252. X * use this file in whole or in part provided that you do not sell it
  253. X * for profit and that this copyright notice is retained unchanged.
  254. X *
  255. X * fbps: Convert a grayscale image to a PostScript file
  256. X *
  257. X * USAGE
  258. X *    % fbps < image > postscript
  259. X *
  260. X * EDITLOG
  261. X *    LastEditDate = Thu Apr 27 10:06:15 1989 - Michael Mauldin
  262. X *    LastFileName = /usr2/mlm/src/misc/fbm/fbps.c
  263. X *
  264. X * HISTORY
  265. X * 27-Apr-89  Michael Mauldin (mlm) at Carnegie Mellon University
  266. X *    Beta release (version 0.92) mlm@cs.cmu.edu
  267. X *
  268. X * 25-Apr-89  Paul Milazzo (milazzo) at BBN
  269. X *    Added color postscript support
  270. X *
  271. X * 27-Aug-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  272. X *    Created.
  273. X *****************************************************************/
  274. X
  275. X# include <stdio.h>
  276. X# include <math.h>
  277. X# include "fbm.h"
  278. X
  279. X# define MAXWIDTH 7.0 /* inches */
  280. X# define MAXHEIGHT 9.5 /* inches */
  281. X
  282. Xchar *ps_chars();
  283. X
  284. X# define USAGE \
  285. X"Usage: fbps [-tT] [-pP] [ -s ] [ -w<width> ] < foo.fbm > foo.PS"
  286. X
  287. X#ifndef lint
  288. Xstatic char *fbmid =
  289. X    "$FBM fbps.c <0.92> 27-Apr-89  (C) 1989 by Michael Mauldin$";
  290. X#endif
  291. X
  292. Xmain (argc, argv)
  293. Xchar *argv[];
  294. X{ register int i, j;
  295. X  int rows, cols, rowlen;
  296. X  double width = -1, height, llx, lly;
  297. X  int bytcnt=0;
  298. X  int dotitle=1, dosize=1, scribe=0;
  299. X  char buf[BUFSIZ], *title=NULL, *creator=NULL;
  300. X  long clock = time ((long *) NULL);
  301. X  char *ctime ();
  302. X  FBM image;
  303. X
  304. X  /* Clear the memory pointer so alloc_fbm won't be confused */
  305. X  image.cm  = image.bm  = (unsigned char *) NULL;
  306. X
  307. X  /* Get the options */
  308. X  while (--argc > 0 && (*++argv)[0] == '-')
  309. X  { while (*++(*argv))
  310. X    { switch (**argv)
  311. X      { case 't':    dotitle = 1; break;
  312. X    case 'T':    dotitle = 0; break;
  313. X    case 'p':    dosize = 1; break;
  314. X    case 'P':    dosize = 0; break;
  315. X    case 's':    scribe++; break;
  316. X    case 'w':    width = atof (*argv+1); SKIPARG; break;
  317. X    default:    fprintf (stderr, "%s\n", USAGE);
  318. X            exit (1);
  319. X      }
  320. X    }
  321. X  }
  322. X
  323. X  if (!read_bitmap (&image, (char *) NULL))
  324. X  { exit (1); }
  325. X
  326. X  if ((image.hdr.planes != 1 && image.hdr.planes != 3) || image.hdr.clrlen > 0)
  327. X  { fprintf (stderr,
  328. X         "Error:\tfbps only handles grayscale or unmapped color files\n");
  329. X    fprintf (stderr, "\tUse the clr2gray filter to create grayscale first\n");
  330. X    exit (1);
  331. X  }
  332. X
  333. X  if (image.hdr.bits == 1)
  334. X  { fprintf (stderr, "Error:\tfbps cannot handle 1 bit deep bitmaps\n");
  335. X    fprintf (stderr, "\tUse 'fbcat -P | pbm2ps' to convert %s\n",
  336. X         "1bit files to Postscript");
  337. X    exit (1);
  338. X  }
  339. X
  340. X  /* Get title */
  341. X  if (image.hdr.title && image.hdr.title[0])
  342. X  { title = image.hdr.title; }
  343. X
  344. X  /* Get width and height */
  345. X  rows = image.hdr.rows;
  346. X  cols = image.hdr.cols;
  347. X  rowlen = image.hdr.rowlen;
  348. X
  349. X  /* Pick output size */
  350. X  if (width < 0.0 || width > MAXWIDTH)
  351. X  { width = MAXWIDTH; }
  352. X  
  353. X  height = width * image.hdr.aspect * (double) rows / cols;
  354. X    
  355. X  if (height > MAXHEIGHT)
  356. X  { width = width * MAXHEIGHT / height; height = MAXHEIGHT; }
  357. X  
  358. X  /* Pick lower left corner */
  359. X  if (scribe)
  360. X  { llx = lly = 0.0;  }
  361. X  else
  362. X  { llx = (8.0 - width) / 2.0 + 0.5;
  363. X    lly = (11.0 - height) / 2.0;
  364. X  }
  365. X
  366. X  fprintf (stderr,
  367. X       "FBM to PS \"%s\" width %1.3lf inches, height %1.3lf inches\n",
  368. X       title ? title : "(untitled)", width, height);
  369. X
  370. X  /* Write out PostScript Header */
  371. X  if (scribe)
  372. X  { printf ("%%! Scribe @graphic style PostScript\n");
  373. X    if (title) { printf ("%%%%Title: %s\n", ps_chars (title)); }
  374. X    if (creator) { printf ("%%%%Creator:  %s\n", ps_chars (creator)); }
  375. X    printf ("%%%%CreationDate: %s", ctime (&clock));
  376. X
  377. X    printf ("/inch { 72 mul } def\n");
  378. X    printf ("/picstr %d string def\n\n", BYTESPERLINE);
  379. X  }
  380. X  else
  381. X  { printf ("%%!\n");
  382. X    if (title) { printf ("%%%%Title: %s\n", ps_chars (title)); }
  383. X    if (creator) { printf ("%%%%Creator:  %s\n", ps_chars (creator)); }
  384. X    printf ("%%%%CreationDate: %s", ctime (&clock));
  385. X    printf ("%%%%Pages: 1\n");
  386. X    printf ("%%%%DocumentFonts:%s%s\n",
  387. X        dotitle ? " Times-Bold" : "",
  388. X        dosize ?  " Times-Roman" : "");
  389. X    printf ("%%%%EndComments\n");
  390. X    printf ("%%%%EndProlog\n");
  391. X    printf ("%%%%Page: 1 1\n\n");
  392. X
  393. X    printf ("/inch { 72 mul } def\n");
  394. X    printf ("/picstr %d string def\n\n", BYTESPERLINE);
  395. X
  396. X    if (dotitle && title)
  397. X    { printf ("/Times-Bold findfont 14 scalefont setfont\n");
  398. X      printf ("%lg inch %lg inch moveto\n", 
  399. X        llx + width/2.0, lly + 0.125 + height);
  400. X      printf ("(%s)\n", ps_chars (title));
  401. X      printf ("dup stringwidth pop 2 div 0 exch sub 0 rmoveto show\n\n");
  402. X    }
  403. X  
  404. X    if (dosize)
  405. X    { printf ("/Times-Roman findfont 8 scalefont setfont\n");
  406. X            printf ("%lg inch %lg inch moveto\n", llx + width, lly - 0.25);
  407. X      sprintf (buf, "[ %d by %d pixels, %1.3lf %s, %1.2lf by %1.2lf inches ]",
  408. X           image.hdr.cols, image.hdr.rows, image.hdr.aspect,
  409. X           "aspect ratio", width, height);
  410. X      printf ("(%s)\n", ps_chars (buf));
  411. X      printf ("dup stringwidth pop 0 exch sub 0 rmoveto show\n\n");
  412. X    }
  413. X
  414. X  }
  415. X
  416. X  printf ("gsave\n");
  417. X
  418. X  if (llx != 0.0 || lly != 0.0)
  419. X  { printf ("%lg inch %lg inch translate ", llx, lly); }
  420. X  
  421. X  printf ("%lg inch %lg inch scale\n", width, height);
  422. X
  423. X  if (image.hdr.planes == 3) {
  424. X    int plane;
  425. X    int plnlen = image.hdr.plnlen;
  426. X    int bits = image.hdr.bits;
  427. X
  428. X    /* use QMS colorimage operator */
  429. X
  430. X    printf ("/redScanLine %d string def\n", cols * 8 / bits);
  431. X    printf ("/greenScanLine %d string def\n", cols * 8 / bits);
  432. X    printf ("/blueScanLine %d string def\n", cols * 8 / bits);
  433. X
  434. X    printf ("%d %d %d [%d 0 0 %d 0 %d]\n",
  435. X        cols, rows, bits, cols, -rows, rows);
  436. X    puts ("{currentfile redScanLine readhexstring pop}");
  437. X    puts ("{currentfile greenScanLine readhexstring pop}");
  438. X    puts ("{currentfile blueScanLine readhexstring pop}");
  439. X    puts ("true 3 colorimage");
  440. X
  441. X    for (j = 0; j < rows; j++) {
  442. X        for (plane = 0; plane < 3; plane++) {
  443. X        for (i = 0; i < cols; i++) {
  444. X            printf ("%02x", image.bm[plane * plnlen + j * rowlen + i]);
  445. X            if (++bytcnt % BYTESPERLINE == 0)
  446. X            putchar ('\n');
  447. X        }
  448. X        bytcnt = 0;
  449. X        putchar ('\n');
  450. X        }
  451. X    }
  452. X  }
  453. X  else {
  454. X    printf ("%d %d 8 [%d 0 0 -%d 0 %d] ", cols, rows, cols, rows, rows);
  455. X    printf ("{ currentfile picstr readhexstring pop }\n");
  456. X    printf ("image\n");
  457. X  
  458. X    /* Write out bitmap */
  459. X    for (j=0; j < rows; j++)  
  460. X    { for (i=0; i < cols; i++)
  461. X      { printf ("%02x", image.bm[j * rowlen + i]);
  462. X
  463. X        if (++bytcnt % BYTESPERLINE == 0) putchar ('\n');
  464. X      }
  465. X  }
  466. X
  467. X  }
  468. X
  469. X  /* Pad so there are exactly BYTESPERLINE bytes in each line */
  470. X  if (bytcnt % BYTESPERLINE)
  471. X  { while (bytcnt++ % BYTESPERLINE) printf ("00");
  472. X    printf ("\n");
  473. X  }
  474. X  
  475. X  printf ("grestore\n");
  476. X
  477. X  if (!scribe)
  478. X  { printf ("\nshowpage\n\n");
  479. X    printf ("%%%%Trailer\n");
  480. X  }
  481. X
  482. X  exit (0);
  483. X}
  484. X
  485. X/****************************************************************
  486. X * ps_chars: Put in proper escapes so an arbitrary string works
  487. X *         according to the PostScript definition of a literal
  488. X ****************************************************************/
  489. X
  490. Xchar *ps_chars (txt)
  491. Xchar *txt;
  492. X{ static char buf[512];
  493. X  register char *s = buf;
  494. X  char *index ();
  495. X  
  496. X  for (; *txt; txt++)
  497. X  { if (index ("()\\", *txt))
  498. X    { *s++ = '\\'; *s++ = *txt; }
  499. X    else if (*txt < ' ' || *txt > '~')
  500. X    { sprintf (s, "\\%03o", *txt & 0377); s += 4; }
  501. X    else
  502. X    { *s++ = *txt; }
  503. X  }
  504. X  *s = '\0';
  505. X  s = buf;
  506. X  return (s);
  507. X}
  508. END_OF_FILE
  509. if test 7399 -ne `wc -c <'fbps.c'`; then
  510.     echo shar: \"'fbps.c'\" unpacked with wrong size!
  511. fi
  512. # end of 'fbps.c'
  513. fi
  514. if test -f 'flclr.c' -a "${1}" != "-c" ; then 
  515.   echo shar: Will not clobber existing file \"'flclr.c'\"
  516. else
  517. echo shar: Extracting \"'flclr.c'\" \(7570 characters\)
  518. sed "s/^X//" >'flclr.c' <<'END_OF_FILE'
  519. X/*****************************************************************
  520. X * flclr.c: FBM Library 0.9 (Beta test) 07-Mar-89  Michael Mauldin
  521. X *
  522. X * Copyright (C) 1989 by Michael Mauldin.  Permission is granted to
  523. X * use this file in whole or in part provided that you do not sell it
  524. X * for profit and that this copyright notice is retained unchanged.
  525. X *
  526. X * flclr.c: Color <--> BW, (Mapped Color | BW) --> unmapped color
  527. X *
  528. X * CONTENTS
  529. X *    clr2gray (input, output, rw, gw, bw)
  530. X *    gray2clr (input, output, sun)
  531. X *
  532. X * EDITLOG
  533. X *    LastEditDate = Thu Apr 20 16:55:23 1989 - Michael Mauldin
  534. X *    LastFileName = /usr2/mlm/src/misc/fbm/flclr.c
  535. X *
  536. X * HISTORY
  537. X * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
  538. X *    Beta release (version 0.9) mlm@cs.cmu.edu
  539. X *
  540. X * 28-Nov-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  541. X *    Created.
  542. X *****************************************************************/
  543. X
  544. X# include <stdio.h>
  545. X# include "fbm.h"
  546. X
  547. X/****************************************************************
  548. X * clr2gray: Apply a triplet of weights to each color in and RGB
  549. X *         or mapped image and produce an 8bit grayscale image
  550. X ****************************************************************/
  551. X
  552. X#ifndef lint
  553. Xstatic char *fbmid =
  554. X    "$FBM flclr.c <0.9> 07-Mar-89  (C) 1989 by Michael Mauldin$";
  555. X#endif
  556. X
  557. Xclr2gray (input, output, rw, gw, bw)
  558. XFBM *input, *output;
  559. Xint rw, gw, bw;
  560. X{ int rw1, gw1, bw1, width, height, clrlen, rowlen, colors;
  561. X  register int i, j;
  562. X  register unsigned char *bmp, *obm;
  563. X
  564. X  /* Already monochrome? */
  565. X  if (input->hdr.planes == 1 && input->hdr.clrlen == 0)
  566. X  { *output = *input; return (1); }
  567. X  
  568. X  /* Invalid raster type */
  569. X  if (input->hdr.planes != 3 && input->hdr.clrlen == 0)
  570. X  { fprintf (stderr,
  571. X     "clr2gray was passed invalid raster type, clrlen %d, planes %d\n",
  572. X     input->hdr.clrlen, input->hdr.planes);
  573. X    return (0);
  574. X  }
  575. X  
  576. X  /* Adjust weights for fast division via shift */
  577. X  rw1 = rw * 256 / (rw + gw + bw);
  578. X  gw1 = gw * 256 / (rw + gw + bw);
  579. X  bw1 = 256 - (rw1+gw1);
  580. X  
  581. X  fprintf (stderr, "Using weights [%2d %2d %2d] ==> <%3d, %3d, %3d>\n",
  582. X       rw, gw, bw, rw1, gw1, bw1);
  583. X
  584. X  /* Allocate output bitmap */
  585. X  output->hdr = input->hdr;
  586. X  output->hdr.clrlen = 0;
  587. X  output->hdr.planes = 1;
  588. X  output->hdr.bits = output->hdr.physbits = 8;
  589. X  alloc_fbm (output);
  590. X  
  591. X  /* Set commonly used vars */
  592. X  width = input->hdr.cols;
  593. X  height = input->hdr.rows;
  594. X  rowlen = input->hdr.rowlen;
  595. X  clrlen = input->hdr.clrlen;
  596. X  colors = clrlen / 3;
  597. X
  598. X  /* Mapped color to gray scale */
  599. X  if (input->hdr.clrlen > 0)
  600. X  { register int *gray;
  601. X  
  602. X    gray = (int *) malloc ((unsigned) input->hdr.clrlen * sizeof (int));
  603. X    
  604. X    for (i=0; i<colors; i++)
  605. X    { gray[i] = (rw1 * input->cm[i] + 
  606. X         gw1 * input->cm[i+colors] + 
  607. X         bw1 * input->cm[i+(colors<<1)]) >> 8;
  608. X
  609. X# ifdef DEBUG
  610. X      fprintf (stderr, "color %3d:  [%3d %3d %3d] => %3d\n",
  611. X        i,
  612. X        input->cm[i],
  613. X        input->cm[i+colors],
  614. X        input->cm[i+colors*2],
  615. X        gray[i]);
  616. X# endif
  617. X
  618. X    }
  619. X    
  620. X    for (j=0; j<height; j++)
  621. X    { bmp = &(input->bm[j*rowlen]);
  622. X      obm = &(output->bm[j*rowlen]);
  623. X      
  624. X      for (i=0; i<width; i++)
  625. X      { *obm++ = gray[*bmp++]; }
  626. X    }
  627. X  }
  628. X         
  629. X
  630. X  /* RGB color to gray scale */
  631. X  else if (input->hdr.planes == 3 && input->hdr.physbits == 8)
  632. X  { register unsigned char *rp, *gp, *bp;
  633. X
  634. X    for (j=0; j<height; j++)
  635. X    { rp = &(input->bm[j*rowlen]);
  636. X      gp = rp + input->hdr.plnlen;
  637. X      bp = gp + input->hdr.plnlen;
  638. X      obm = (&output->bm[j*rowlen]);
  639. X
  640. X      for (i=0; i<width; i++)
  641. X      { *obm++ = (rw1 * *rp++ + 
  642. X          gw1 * *gp++ + 
  643. X          bw1 * *bp++) >> 8;
  644. X      }
  645. X    }
  646. X  }
  647. X  
  648. X  return (1);
  649. X}
  650. X
  651. X/****************************************************************
  652. X * gray2clr: Add a colormap (shades of gray) to a grayscale file
  653. X ****************************************************************/
  654. X
  655. Xgray2clr (input, output, sun_map)
  656. XFBM *input, *output;
  657. Xint sun_map;
  658. X{ register unsigned char *rmap, *gmap, *bmap, *bmp, *obm;
  659. X  register int i, maplen, plnlen;
  660. X
  661. X  /* Invalid raster type */
  662. X  if (input->hdr.planes == 3)
  663. X  { fprintf (stderr, "Input already is in RGB format\n");
  664. X    *output = *input; return (1);
  665. X  }
  666. X    
  667. X  /* Invalid raster type */
  668. X  if (input->hdr.clrlen > 0 )
  669. X  { fprintf (stderr, "Input already has color map with %d colors\n",
  670. X         input->hdr.clrlen / 3);
  671. X    *output = *input; return (1);
  672. X  }
  673. X
  674. X  /* Invalid raster type */
  675. X  if (input->hdr.planes != 1 || input->hdr.clrlen != 0)
  676. X  { fprintf (stderr,
  677. X     "gray2clr was passed invalid raster type, clrlen %d, planes %d\n",
  678. X     input->hdr.clrlen, input->hdr.planes);
  679. X    return (0);
  680. X  }
  681. X  
  682. X  plnlen = input->hdr.plnlen;
  683. X  
  684. X  /* Make colormap length power of two */
  685. X  maplen = 1 << input->hdr.bits;
  686. X
  687. X  /* Allocate output bitmap */
  688. X  output->hdr = input->hdr;
  689. X  output->hdr.clrlen = maplen * 3;
  690. X  alloc_fbm (output);
  691. X  
  692. X  rmap = &(output->cm[0]);
  693. X  gmap = &(output->cm[maplen]);
  694. X  bmap = &(output->cm[2*maplen]);
  695. X
  696. X  for (i=0; i<maplen; i++)
  697. X  { *rmap++ = *gmap++ = *bmap++ = i; }
  698. X
  699. X  /* For sun_map, swap colors 0 and 255 */
  700. X  if (sun_map && (maplen == 256))
  701. X  { rmap = &(output->cm[0]);
  702. X    gmap = &(output->cm[maplen]);
  703. X    bmap = &(output->cm[2*maplen]);
  704. X
  705. X    rmap[0] = gmap[0] = bmap[0] = 255;
  706. X    rmap[255] = gmap[255] = bmap[255] = 0;
  707. X
  708. X    /* Copy bits */
  709. X    for (bmp = input->bm, obm = output-> bm, i=0; i<plnlen; i++, bmp++)
  710. X    { if (*bmp == 0)        *obm++ = 255;
  711. X      else if (*bmp == 255)    *obm++ = 0;
  712. X      else            *obm++ = *bmp;
  713. X    }
  714. X  }
  715. X
  716. X  else  
  717. X  {
  718. X    /* Copy bits */
  719. X    for (bmp = input->bm, obm = output-> bm, i=0; i<plnlen; i++)
  720. X    { *obm++ = *bmp++; }
  721. X  }
  722. X
  723. X  return (1);
  724. X}
  725. X
  726. X/****************************************************************
  727. X * clr_unmap: Convert a mapped color image into RGB
  728. X ****************************************************************/
  729. X
  730. Xclr_unmap (input, output)
  731. XFBM *input, *output;
  732. X{ register unsigned char *red, *grn, *blu, *bmp, *obm, *tail;
  733. X  register int plnlen, k;
  734. X
  735. X  if (input->hdr.planes == 3)
  736. X  { *output = *input; return (1); }
  737. X
  738. X  if (input->hdr.planes != 1)
  739. X  { fprintf (stderr, "clr_unmap cannot handle images with %d planes\n", 
  740. X         input->hdr.planes);
  741. X    return (0);
  742. X  }
  743. X
  744. X  if (input->hdr.physbits != 8)
  745. X  { fprintf (stderr, "clr_unmap cannot handle images with %d physbits\n", 
  746. X         input->hdr.physbits);
  747. X    return (0);
  748. X  }
  749. X
  750. X  output->hdr = input->hdr;
  751. X  output->hdr.planes = 3;
  752. X  output->hdr.clrlen = 0;
  753. X  output->hdr.bits = output->hdr.physbits;
  754. X  
  755. X  alloc_fbm (output);
  756. X
  757. X  /* Real mapped color image */
  758. X  if (input->hdr.clrlen > 0)
  759. X  { red = &(input->cm[0]);
  760. X    grn = red + input->hdr.clrlen / 3;
  761. X    blu = grn + input->hdr.clrlen / 3;
  762. X    plnlen = input->hdr.plnlen;
  763. X    
  764. X    bmp = input->bm;
  765. X    obm = output->bm;
  766. X    tail = bmp + plnlen;
  767. X    
  768. X    while (bmp < tail)
  769. X    { k = *bmp++;
  770. X    
  771. X      obm[0]            = red[k];
  772. X      obm[plnlen]        = grn[k];
  773. X      obm[plnlen+plnlen]    = blu[k];
  774. X      obm++;
  775. X    }
  776. X    
  777. X  }
  778. X  
  779. X  /* Grayscale image (just duplicate planes) */
  780. X  else
  781. X  { plnlen = input->hdr.plnlen;
  782. X  
  783. X    bmp = input->bm;
  784. X    tail = bmp + plnlen;
  785. X    
  786. X    red = output->bm;
  787. X    grn = red + plnlen;
  788. X    blu = grn + plnlen;
  789. X    
  790. X    while (bmp < tail)
  791. X    { *red++ = *grn++ = *blu++ = *bmp++; }
  792. X  }
  793. X  
  794. X  return (1);
  795. X}
  796. X
  797. X/****************************************************************
  798. X * copy_clr: Copy colormap from input to output
  799. X ****************************************************************/
  800. X
  801. Xcopy_clr (input, output)
  802. XFBM *input, *output;
  803. X{ register int i, clrlen;
  804. X  register unsigned char *ic, *oc;
  805. X
  806. X  output->hdr.clrlen = clrlen = input->hdr.clrlen;
  807. X
  808. X  ic = input->cm;
  809. X  oc = output->cm;
  810. X  
  811. X  for (i=0; i < clrlen; i++)
  812. X  { *oc++ = *ic++; }
  813. X}
  814. END_OF_FILE
  815. if test 7570 -ne `wc -c <'flclr.c'`; then
  816.     echo shar: \"'flclr.c'\" unpacked with wrong size!
  817. fi
  818. # end of 'flclr.c'
  819. fi
  820. if test -f 'fledge.c' -a "${1}" != "-c" ; then 
  821.   echo shar: Will not clobber existing file \"'fledge.c'\"
  822. else
  823. echo shar: Extracting \"'fledge.c'\" \(8359 characters\)
  824. sed "s/^X//" >'fledge.c' <<'END_OF_FILE'
  825. X/*****************************************************************
  826. X * fledge.c: FBM Library 0.9 (Beta test) 07-Mar-89  Michael Mauldin
  827. X *
  828. X * Copyright (C) 1989 by Gary Sherwin & Michael Mauldin.
  829. X * Permission is granted to use this file in whole or in part provided
  830. X * that you do not sell it for profit and that this copyright notice
  831. X * is retained unchanged.
  832. X *
  833. X * fledge.c:
  834. X *
  835. X * CONTENTS
  836. X *    findedge_fbm (&image, beta)
  837. X *
  838. X * EDITLOG
  839. X *    LastEditDate = Tue Mar  7 19:56:54 1989 - Michael Mauldin
  840. X *    LastFileName = /usr2/mlm/src/misc/fbm/fledge.c
  841. X *
  842. X * HISTORY
  843. X * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
  844. X *    Beta release (version 0.9) mlm@cs.cmu.edu
  845. X *
  846. X * 21-Aug-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  847. X *    Created.
  848. X *****************************************************************/
  849. X
  850. X# include <stdio.h>
  851. X# include <math.h>
  852. X# include <ctype.h>
  853. X# include "fbm.h"
  854. X
  855. X/****************************************************************
  856. X * findedge_fbm: determine whether image is in color, and call the
  857. X *            appropriate edge detection routine.
  858. X ****************************************************************/
  859. X
  860. X#ifndef lint
  861. Xstatic char *fbmid =
  862. X    "$FBM fledge.c <0.9> 07-Mar-89  (C) 1989 by Michael Mauldin$";
  863. X#endif
  864. X
  865. Xfindedge_fbm (input, output, beta)
  866. XFBM *input, *output;
  867. Xint beta;
  868. X{
  869. X  if (input->hdr.planes == 1)
  870. X  { return (findedge_bw (input, output, beta)); }
  871. X  else
  872. X  { return (findedge_bw (input, output, beta)); }
  873. X}
  874. X
  875. X/****************************************************************
  876. X * findedge_bw: use a digital Laplacian filter to edge detect a BW image
  877. X ****************************************************************/
  878. X
  879. Xfindedge_bw (input, output, beta)
  880. XFBM *input, *output;
  881. Xint beta;
  882. X{ register unsigned char *bmp, *obm;
  883. X  register int i, j, rowlen, w, h;
  884. X  int new, sum;
  885. X  int bf, wf, tf; /* white and black pixel counters */
  886. X
  887. X/* Filter Chip
  888. X*
  889. X*
  890. X* UL, UC, UR
  891. X* CL, CC, CR
  892. X* BL, BC, BR
  893. X*
  894. X*/
  895. X
  896. X  if (input->hdr.planes != 1)
  897. X  { fprintf (stderr, "findedge_bw: can't process color images\n");
  898. X    return (0);
  899. X  }
  900. X
  901. X  fprintf (stderr, "Edge detect BW, beta %d\n", beta);
  902. X
  903. X  /* Allocate output */
  904. X  output->hdr = input->hdr;
  905. X  alloc_fbm (output);
  906. X
  907. X  w = input->hdr.cols;
  908. X  h = input->hdr.rows;
  909. X  rowlen = input->hdr.rowlen;
  910. X
  911. X  /* Set pixel counters for image statistics */
  912. X  bf = wf = tf = 0;
  913. X
  914. X  /* Compute outer border of pixels */
  915. X    /* Compute Top Line U of Pixels */
  916. X      /* Compute ULPixel */
  917. X   
  918. X  j=0;
  919. X  { bmp = &(input->bm[j*rowlen]);
  920. X    obm = &(output->bm[j*rowlen]);
  921. X    
  922. X    i=0;
  923. X    { sum = 0;
  924. X      sum = sum + (bmp[i]*(-3)     + bmp[i+1]       );
  925. X      sum = sum + (bmp[i+rowlen]   + bmp[i+rowlen+1]);
  926. X      sum = (sum * 8) / 3;
  927. X
  928. X      if (sum > beta) { new = BLACK; bf++; }
  929. X      else { new = WHITE; wf++; }
  930. X
  931. X      tf++;
  932. X
  933. X      obm[i] = new;
  934. X
  935. X    }
  936. X
  937. X    /* Compute URPixel */
  938. X   
  939. X    i=w;
  940. X    { sum = 0;
  941. X      sum = sum + (bmp[i-1]*(-3)     + bmp[i]         ) ;
  942. X      sum = sum + (bmp[i+rowlen-1]   + bmp[i+rowlen]  ) ;
  943. X      sum = (sum * 8) / 3;
  944. X
  945. X      if (sum > beta) { new = BLACK; bf++; }
  946. X      else { new = WHITE; wf++; }
  947. X
  948. X      tf++;
  949. X
  950. X      obm[i] = new;
  951. X
  952. X    }
  953. X
  954. X   /* Compute Rest of U1 Line */
  955. X  
  956. X    for (i=1; i < w-1; i++)
  957. X    { sum = 0;
  958. X      sum = sum + (bmp[i-1]*(-5)   + bmp[i]        + bmp[i+1]       ) ;
  959. X      sum = sum + (bmp[i+rowlen-1] + bmp[i+rowlen] + bmp[i+rowlen+1]) ;
  960. X      sum = (sum * 8) / 5;
  961. X
  962. X      if (sum > beta) { new = BLACK; bf++; }
  963. X        else { new = WHITE; wf++; }
  964. X
  965. X      tf++;
  966. X
  967. X      obm[i] = new;
  968. X
  969. X    }
  970. X  }
  971. X
  972. X  /* Compute Left and Right borders */
  973. X  
  974. X  for (j=1; j < h-1; j++)
  975. X  { bmp = &(input->bm[j*rowlen]);
  976. X    obm = &(output->bm[j*rowlen]);
  977. X
  978. X    /* Compute L Pixel */   
  979. X    i=0;
  980. X    { sum = 0;
  981. X      sum = sum + (bmp[i-rowlen]   + bmp[i-rowlen+1]) ;
  982. X      sum = sum + (bmp[i]*(-5)     + bmp[i+1]       ) ;
  983. X      sum = sum + (bmp[i+rowlen]   + bmp[i+rowlen+1]) ;
  984. X      sum = (sum * 8) / 5;
  985. X
  986. X      if (sum > beta) { new = BLACK; bf++; }
  987. X      else { new = WHITE; wf++; }
  988. X
  989. X      tf++;
  990. X
  991. X      obm[i] = new;
  992. X
  993. X    }
  994. X
  995. X
  996. X    /* Compute R1Pixel */
  997. X    i=w;
  998. X    { sum = 0;
  999. X      sum = sum + (bmp[i-rowlen-1]   + bmp[i-rowlen]  ) ;
  1000. X      sum = sum + (bmp[i-1]          + bmp[i]*(-5)    ) ;
  1001. X      sum = sum + (bmp[i+rowlen-1]   + bmp[i+rowlen]  ) ;
  1002. X      sum = (sum * 8) / 5;
  1003. X
  1004. X      if (sum > beta) { new = BLACK; bf++; }
  1005. X      else { new = WHITE; wf++; }
  1006. X      tf++;
  1007. X
  1008. X      obm[i] = new;
  1009. X
  1010. X    }
  1011. X  }
  1012. X
  1013. X    /* Compute Bottom Line B of Pixels */
  1014. X    /* Compute BL Pixel */ 
  1015. X  j=h;
  1016. X  { bmp = &(input->bm[j*rowlen]);
  1017. X    obm = &(output->bm[j*rowlen]);
  1018. X    
  1019. X    i=0;
  1020. X    { sum = 0;
  1021. X      sum = sum + (bmp[i-rowlen]   + bmp[i-rowlen+1]) ;
  1022. X      sum = sum + (bmp[i]*(-3)     + bmp[i+1]       ) ;
  1023. X      sum = (sum * 8) / 3;
  1024. X
  1025. X      if (sum > beta) { new = BLACK; bf++; }
  1026. X      else { new = WHITE; wf++; }
  1027. X      tf++;
  1028. X
  1029. X      obm[i] = new;
  1030. X
  1031. X    }
  1032. X
  1033. X       /* Compute BR Pixel */
  1034. X
  1035. X    i=w;
  1036. X    { sum = 0;
  1037. X      sum = sum + (bmp[i-rowlen-1]   + bmp[i-rowlen]  ) ;
  1038. X      sum = sum + (bmp[i-1]          + bmp[i]*(-3)    ) ;
  1039. X      sum = (sum * 8) / 3;
  1040. X
  1041. X      if (sum > beta) { new = BLACK; bf++; }
  1042. X      else { new = WHITE; wf++; }
  1043. X
  1044. X      tf++;
  1045. X
  1046. X      obm[i] = new;
  1047. X
  1048. X    }
  1049. X
  1050. X      /* Compute Rest of B1 Line */
  1051. X
  1052. X    for (i=1; i < w-1; i++)
  1053. X    { sum = 0;
  1054. X      sum = sum + (bmp[i-rowlen-1]   + bmp[i-rowlen]   + bmp[i-rowlen+1]) ;
  1055. X      sum = sum + (bmp[i-1]          + bmp[i]*(-5)     + bmp[i+1]       ) ;
  1056. X      sum = (sum * 8) / 5;
  1057. X
  1058. X      if (sum > beta) { new = BLACK; bf++; }
  1059. X      else { new = WHITE; wf++; }
  1060. X
  1061. X      tf++;
  1062. X
  1063. X      obm[i] = new;
  1064. X
  1065. X    }
  1066. X  }
  1067. X
  1068. X  /* Compute Main Image Body */
  1069. X
  1070. X  for (j=1; j < h-1; j++)
  1071. X  { bmp = &(input->bm[j*rowlen]);
  1072. X    obm = &(output->bm[j*rowlen]);
  1073. X    
  1074. X    for (i=1; i < w-1; i++)
  1075. X    { sum = 0;
  1076. X      sum = sum + (bmp[i-rowlen-1]   + bmp[i-rowlen]   + bmp[i-rowlen+1]) ;
  1077. X      sum = sum + (bmp[i-1]          + bmp[i]*(-8)     + bmp[i+1]       ) ;
  1078. X      sum = sum + (bmp[i+rowlen-1]   + bmp[i+rowlen]   + bmp[i+rowlen+1]) ;
  1079. X
  1080. X      if (sum > beta) { new = BLACK; bf++; }
  1081. X      else { new = WHITE; wf++; }
  1082. X
  1083. X      tf++;
  1084. X
  1085. X      obm[i] = new;
  1086. X
  1087. X    }
  1088. X  }
  1089. X
  1090. X  fprintf (stderr, "Edge detection complete for slope of %2d for %d pixels.\n", beta, tf);
  1091. X  fprintf (stderr, "Detected %d white pixels and %d black pixels.\n", bf, wf);
  1092. X
  1093. X  return (1);
  1094. X}
  1095. X
  1096. X/****************************************************************
  1097. X * findedge_clr: use a digital Laplacian filter to edge detect a CLR image
  1098. X ****************************************************************/
  1099. X
  1100. Xfindedge_clr (input, output, beta)
  1101. XFBM *input, *output;
  1102. Xdouble beta;
  1103. X{ register unsigned char *bmp, *obm, *avg;
  1104. X  register int i, j, k, rowlen, plnlen, w, h, p, sum;
  1105. X  int new, delta, beta100 = beta * 100;
  1106. X  unsigned char *gray;
  1107. X
  1108. X  fprintf (stderr, "Sharpen color, beta %lg\n", beta);
  1109. X
  1110. X  /* Allocate output */
  1111. X  output->hdr = input->hdr;
  1112. X  alloc_fbm (output);
  1113. X
  1114. X  w = input->hdr.cols;
  1115. X  h = input->hdr.rows;
  1116. X  p = input->hdr.planes;
  1117. X  rowlen = input->hdr.rowlen;
  1118. X  plnlen = input->hdr.plnlen;
  1119. X  
  1120. X  /* Calculate the intensity plane */
  1121. X  gray = (unsigned char *) malloc (plnlen);
  1122. X
  1123. X  for (j=0; j<h; j++)  
  1124. X  { bmp = &(input->bm[j*rowlen]);
  1125. X    avg = &(gray[j*rowlen]);    
  1126. X
  1127. X    for (i=0; i<w; i++)
  1128. X    { sum = 0;
  1129. X      for (k=0; k<p; k++)
  1130. X      { sum += bmp[i+k*plnlen]; }
  1131. X      avg[i] = sum/p;
  1132. X    }
  1133. X  }
  1134. X  
  1135. X  /* Copy edges directly */
  1136. X  for (k=0; k<p; k++)
  1137. X  {  for (j=0; j<h; j++)
  1138. X    { output->bm[k*plnlen + j*rowlen] =
  1139. X    input->bm[k*plnlen + j*rowlen];
  1140. X      output->bm[k*plnlen + j*rowlen + w-1] =
  1141. X    input->bm[k*plnlen + j*rowlen + w-1];
  1142. X    }
  1143. X  
  1144. X    for (i=0; i<w; i++)
  1145. X    { output->bm[k*plnlen + i] =
  1146. X    input->bm[k*plnlen + i];
  1147. X      output->bm[k*plnlen + (h-1)*rowlen + i] =
  1148. X    input->bm[k*plnlen + (h-1)*rowlen + i];
  1149. X    }
  1150. X  }
  1151. X
  1152. X  for (j=1; j < h-1; j++)
  1153. X  { avg = &(gray[j*rowlen]);
  1154. X    
  1155. X    for (i=1; i < w-1; i++)
  1156. X    { sum = avg[i-rowlen-1] +     avg[i-rowlen] + avg[i-rowlen+1] +
  1157. X        avg[i-1]        - 8 * avg[i]        + avg[i+1]        +
  1158. X        avg[i+rowlen-1] +     avg[i+rowlen] + avg[i+rowlen+1];
  1159. X
  1160. X      for (k=0; k<p; k++)
  1161. X      { bmp =  &(input->bm[k*plnlen + j*rowlen + i]);
  1162. X        obm = &(output->bm[k*plnlen + j*rowlen + i]);
  1163. X        
  1164. X    if (sum < 0)
  1165. X    { delta = - (beta100 * *bmp * -sum / (8*100)); }
  1166. X    else
  1167. X    { delta = beta100 * *bmp * sum / (8*100); }
  1168. X  
  1169. X    new = *bmp - delta;
  1170. X  
  1171. X    if (new < BLACK) new = BLACK;
  1172. X    else if (new > WHITE) new = WHITE;
  1173. X    
  1174. X    *obm = new;
  1175. X      }
  1176. X    }
  1177. X  }
  1178. X}
  1179. END_OF_FILE
  1180. if test 8359 -ne `wc -c <'fledge.c'`; then
  1181.     echo shar: \"'fledge.c'\" unpacked with wrong size!
  1182. fi
  1183. # end of 'fledge.c'
  1184. fi
  1185. if test -f 'flklnr.c' -a "${1}" != "-c" ; then 
  1186.   echo shar: Will not clobber existing file \"'flklnr.c'\"
  1187. else
  1188. echo shar: Extracting \"'flklnr.c'\" \(6703 characters\)
  1189. sed "s/^X//" >'flklnr.c' <<'END_OF_FILE'
  1190. X/*****************************************************************
  1191. X * flklnr.c: FBM Library 0.9 (Beta test) 07-Mar-89  Michael Mauldin
  1192. X *
  1193. X * Copyright (C) 1989 by Michael Mauldin.  Permission is granted to
  1194. X * use this file in whole or in part provided that you do not sell it
  1195. X * for profit and that this copyright notice is retained unchanged.
  1196. X *
  1197. X * fbm.c: 
  1198. X *
  1199. X * USAGE
  1200. X *    clean_fbm (input, output, beta, gamma, nbr)
  1201. X *
  1202. X * EDITLOG
  1203. X *    LastEditDate = Tue Mar  7 19:57:19 1989 - Michael Mauldin
  1204. X *    LastFileName = /usr2/mlm/src/misc/fbm/flklnr.c
  1205. X *
  1206. X * HISTORY
  1207. X * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
  1208. X *    Beta release (version 0.9) mlm@cs.cmu.edu
  1209. X *
  1210. X * 21-Aug-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  1211. X *    Created.
  1212. X *****************************************************************/
  1213. X
  1214. X# include <stdio.h>
  1215. X# include <math.h>
  1216. X# include <ctype.h>
  1217. X# include "fbm.h"
  1218. X
  1219. X/****************************************************************
  1220. X * clean_fbm: determine whether image is in color, and call the
  1221. X *            appropriate cleaning routine.
  1222. X ****************************************************************/
  1223. X
  1224. X#ifndef lint
  1225. Xstatic char *fbmid =
  1226. X    "$FBM flklnr.c <0.9> 07-Mar-89  (C) 1989 by Michael Mauldin$";
  1227. X#endif
  1228. X
  1229. Xclean_fbm (input, output, beta, gamma, nbr)
  1230. XFBM *input, *output;
  1231. Xint beta, gamma, nbr;
  1232. X{
  1233. X  if (input->hdr.planes == 1)
  1234. X  { return (clean_bw (input, output, beta, gamma, nbr)); }
  1235. X  else
  1236. X  { return (clean_bw (input, output, beta, gamma, nbr)); }
  1237. X}
  1238. X
  1239. X/****************************************************************
  1240. X * clean_bw: use a digital Laplacian filter to clean a BW image
  1241. X ****************************************************************/
  1242. X
  1243. Xclean_bw (input, output, beta, gamma, nbr)
  1244. XFBM *input, *output;
  1245. Xint beta, gamma, nbr;
  1246. X{ register unsigned char *obm, *bmp;
  1247. X  register int dx, dy, left, right, top, bot, i, j;
  1248. X  int rowlen, w, h, off, cnt;
  1249. X  int new, sum, sumw, sumb, Whites;
  1250. X  int bf, wf, ubf, uwf; /* white and black pixel counters */
  1251. X
  1252. X  double pc;
  1253. X
  1254. X  if (input->hdr.planes != 1)
  1255. X  { fprintf (stderr, "clean_bw: can't process color images\n");
  1256. X    return (0);
  1257. X  }
  1258. X
  1259. X  fprintf (stderr, "Clean BW, beta %d, gamma %d, nbr %d\n",
  1260. X       beta, gamma, nbr);
  1261. X
  1262. X  /* Allocate output */
  1263. X  output->hdr = input->hdr;
  1264. X  alloc_fbm (output);
  1265. X
  1266. X  w = input->hdr.cols;
  1267. X  h = input->hdr.rows;
  1268. X  rowlen = input->hdr.rowlen;
  1269. X  Whites = 252;
  1270. X
  1271. X  /* If not edge detect do black white trip point */
  1272. X  if (gamma > 0)
  1273. X  {
  1274. X    fprintf (stderr, "Thresholding image, gamma %d...\n", gamma);
  1275. X    bf = wf = 0;
  1276. X    for (j=0; j < h; j++)
  1277. X    { bmp = &(input->bm[j*rowlen]);
  1278. X
  1279. X      for (i=0; i < w; i++)
  1280. X      {
  1281. X        if (bmp[i] >= gamma)    { bmp[i] = WHITE; wf++; }
  1282. X        else            { bmp[i] = BLACK; bf++; }
  1283. X      }
  1284. X    }
  1285. X
  1286. X    pc = (((double)bf) * 100.00) / ((double)(bf + wf));
  1287. X    fprintf (stderr, "Converted to %1.2f %% Black, %1.2f %% White image.\n",
  1288. X         pc, (100.00 - pc));
  1289. X  }
  1290. X
  1291. X  /* Set pixel counters for image statistics */
  1292. X  bf = wf = ubf = uwf = 0;
  1293. X  off = nbr/2;
  1294. X
  1295. X  /* Compute outer border of 2 pixels */
  1296. X    /* Compute Top Line U1 of Pixels */
  1297. X      /* Compute U1L1Pixel */
  1298. X
  1299. X  /* Compute Main Image Body */
  1300. X  for (j=0; j<h; j++)
  1301. X  { obm = &(output->bm[j*rowlen]);
  1302. X
  1303. X    /* Set limits of neighborhood */
  1304. X    top   =  j-off;        if (top < 0)    top = 0;
  1305. X    bot   =  top+nbr;        if (bot > h)    bot = h;
  1306. X
  1307. X    for (i=0; i<w; i++)
  1308. X    { sum = 0;
  1309. X      cnt = 0;
  1310. X      
  1311. X      /* Set limits of neighborhood */
  1312. X      left  =  i-off;        if (left < 0)    left = 0;
  1313. X      right =  left+nbr;    if (right > w)    right = w;
  1314. X      
  1315. X      /* Sample neighborhood */
  1316. X      bmp = &(input->bm[top*rowlen]);
  1317. X    
  1318. X      for (dy = top;   dy < bot;   dy++, bmp += rowlen)
  1319. X      { for (dx = left;   dx < right;   dx++)
  1320. X        { sum += bmp[dx]; cnt ++; }
  1321. X      }
  1322. X      
  1323. X      if (cnt == 0)
  1324. X      { fprintf (stderr, "Panic, no pixels in neighborhood!\n");
  1325. X        abort ();
  1326. X      }
  1327. X      
  1328. X      sumw = sum * 100 / (WHITE * cnt);
  1329. X      sumb = 100 - sumw;
  1330. X      
  1331. X      if (input->bm[i + j*rowlen] > Whites)
  1332. X      {
  1333. X        if (sumw < beta) { new = BLACK; bf++; }
  1334. X        else { new = WHITE; uwf++; }
  1335. X      }
  1336. X      else
  1337. X      {
  1338. X        if (sumb < beta) { new = WHITE; wf++; }
  1339. X        else { new = BLACK; ubf++; }
  1340. X      }
  1341. X
  1342. X      obm[i] = new;
  1343. X    }
  1344. X  }
  1345. X
  1346. X
  1347. X  fprintf (stderr, "Cleaning pass complete for %2d neighbors of %d pixels.\n",
  1348. X       beta, w*h);
  1349. X  fprintf (stderr, "Removed %d white pixels and %d black pixels.\n", bf, wf);
  1350. X  fprintf (stderr, "Left Unchanged %d white and %d black pixels.\n", uwf, ubf);
  1351. X
  1352. X  return (1);
  1353. X}
  1354. X
  1355. X# ifdef UNDEFINED
  1356. X/****************************************************************
  1357. X * clean_clr: use a digital Laplacian filter to edge detect a CLR image
  1358. X ****************************************************************/
  1359. X
  1360. Xclean_clr (input, output, beta)
  1361. XFBM *input, *output;
  1362. Xdouble beta;
  1363. X{ register unsigned char *b, *obm, *avg;
  1364. X  register int i, j, k, rowlen, plnlen, w, h, p, sum;
  1365. X  int new, delta, beta100 = beta * 100;
  1366. X  unsigned char gray[500000];
  1367. X
  1368. X  fprintf (stderr, "Sharpen color, beta %lg\n", beta);
  1369. X
  1370. X  /* Allocate output */
  1371. X  output->hdr = input->hdr;
  1372. X  alloc_fbm (output);
  1373. X
  1374. X  w = input->hdr.cols;
  1375. X  h = input->hdr.rows;
  1376. X  p = input->hdr.planes;
  1377. X  rowlen = input->hdr.rowlen;
  1378. X  plnlen = input->hdr.plnlen;
  1379. X  
  1380. X  /* Calculate the intensity plane */
  1381. X/*  gray = (unsigned char *) malloc (plnlen); */
  1382. X  
  1383. X  fprintf (stderr, "Allocating %d bytes for gray[]\n", plnlen);
  1384. X
  1385. X  for (j=0; j<h; j++)  
  1386. X  { b = &(input->bm[j*rowlen]);
  1387. X    avg = &(gray[j*rowlen]);    
  1388. X
  1389. X    for (i=0; i<w; i++)
  1390. X    { sum = 0;
  1391. X      for (k=0; k<p; k++)
  1392. X      { sum += b[i+k*plnlen]; }
  1393. X      avg[i] = sum/p;
  1394. X    }
  1395. X  }
  1396. X  
  1397. X  /* Copy edges directly */
  1398. X  for (k=0; k<p; k++)
  1399. X  {  for (j=0; j<h; j++)
  1400. X    { output->bm[k*plnlen + j*rowlen] =
  1401. X    input->bm[k*plnlen + j*rowlen];
  1402. X      output->bm[k*plnlen + j*rowlen + w-1] =
  1403. X    input->bm[k*plnlen + j*rowlen + w-1];
  1404. X    }
  1405. X  
  1406. X    for (i=0; i<w; i++)
  1407. X    { output->bm[k*plnlen + i] =
  1408. X    input->bm[k*plnlen + i];
  1409. X      output->bm[k*plnlen + (h-1)*rowlen + i] =
  1410. X    input->bm[k*plnlen + (h-1)*rowlen + i];
  1411. X    }
  1412. X  }
  1413. X
  1414. X  for (j=1; j < h-1; j++)
  1415. X  { avg = &(gray[j*rowlen]);
  1416. X    
  1417. X    for (i=1; i < w-1; i++)
  1418. X    { sum = avg[i-rowlen-1] +     avg[i-rowlen] + avg[i-rowlen+1] +
  1419. X        avg[i-1]        - 8 * avg[i]        + avg[i+1]        +
  1420. X        avg[i+rowlen-1] +     avg[i+rowlen] + avg[i+rowlen+1];
  1421. X
  1422. X      for (k=0; k<p; k++)
  1423. X      { b =  &(input->bm[k*plnlen + j*rowlen + i]);
  1424. X        obm = &(output->bm[k*plnlen + j*rowlen + i]);
  1425. X        
  1426. X    if (sum < 0)
  1427. X    { delta = - (beta100 * *b * -sum / (8*100)); }
  1428. X    else
  1429. X    { delta = beta100 * *b * sum / (8*100); }
  1430. X  
  1431. X    new = *b - delta;
  1432. X  
  1433. X    if (new < BLACK) new = BLACK;
  1434. X    else if (new > WHITE) new = WHITE;
  1435. X    
  1436. X    *obm = new;
  1437. X      }
  1438. X    }
  1439. X  }
  1440. X
  1441. X  return (1);
  1442. X}
  1443. X# endif
  1444. END_OF_FILE
  1445. if test 6703 -ne `wc -c <'flklnr.c'`; then
  1446.     echo shar: \"'flklnr.c'\" unpacked with wrong size!
  1447. fi
  1448. # end of 'flklnr.c'
  1449. fi
  1450. if test -f 'flsun.c' -a "${1}" != "-c" ; then 
  1451.   echo shar: Will not clobber existing file \"'flsun.c'\"
  1452. else
  1453. echo shar: Extracting \"'flsun.c'\" \(8735 characters\)
  1454. sed "s/^X//" >'flsun.c' <<'END_OF_FILE'
  1455. X/*****************************************************************
  1456. X * flsun.c: FBM Library 0.94 (Beta test) 20-May-89  Michael Mauldin
  1457. X *
  1458. X * Copyright (C) 1989 by Michael Mauldin.  Permission is granted to
  1459. X * use this file in whole or in part provided that you do not sell it
  1460. X * for profit and that this copyright notice is retained unchanged.
  1461. X *
  1462. X * flsun.c: 
  1463. X *
  1464. X * CONTENTS
  1465. X *    read_sun (image, rfile, mstr, mlen)
  1466. X *    write_sun (image, wfile)
  1467. X *
  1468. X * EDITLOG
  1469. X *    LastEditDate = Sat May 20 19:08:32 1989 - Michael Mauldin
  1470. X *    LastFileName = /usr2/mlm/src/misc/fbm/flsun.c
  1471. X *
  1472. X * HISTORY
  1473. X * 20-May-89  Michael Mauldin (mlm) at Carnegie Mellon University
  1474. X *    Fixed problem with odd length rows on reading
  1475. X *
  1476. X * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
  1477. X *    Beta release (version 0.9) mlm@cs.cmu.edu
  1478. X *
  1479. X * 12-Nov-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  1480. X *    Created.
  1481. X *****************************************************************/
  1482. X
  1483. X# include <stdio.h>
  1484. X# include <math.h>
  1485. X# include <ctype.h>
  1486. X# include "fbm.h"
  1487. X
  1488. Xtypedef struct rasterfile {
  1489. X    long ras_magic;
  1490. X    long ras_width;
  1491. X    long ras_height;
  1492. X    long ras_depth;
  1493. X    long ras_length;
  1494. X    long ras_type;
  1495. X    long ras_maptype;
  1496. X    long ras_maplength;
  1497. X} RASHDR;
  1498. X
  1499. X# define RT_STANDARD    1
  1500. X# define RMT_NONE    0
  1501. X# define RMT_EQUAL_RGB    1
  1502. X# define RMT_RAW    2
  1503. X
  1504. X# define RED 0
  1505. X# define GRN 1
  1506. X# define BLU 2
  1507. X
  1508. X/****************************************************************
  1509. X * write_sun (image, wfile)
  1510. X ****************************************************************/
  1511. X
  1512. X#ifndef lint
  1513. Xstatic char *fbmid =
  1514. X    "$FBM flsun.c <0.9> 07-Mar-89  (C) 1989 by Michael Mauldin$";
  1515. X#endif
  1516. X
  1517. Xwrite_sun (image, wfile)
  1518. XFBM *image;
  1519. XFILE *wfile;
  1520. X{ RASHDR rhdr;
  1521. X  register int i, j, byte;
  1522. X  register unsigned char *bmp, *rp, *gp, *bp;
  1523. X  int width, height, plnlen, clrlen, rowlen, depth, bits;
  1524. X
  1525. X  if (image->hdr.planes != 1 && image->hdr.planes != 3)
  1526. X  { fprintf (stderr,
  1527. X         "Error, write_sun can only handle images with depth 1 or 3\n");
  1528. X    return (0);
  1529. X  }
  1530. X
  1531. X  if (image->hdr.physbits != 8)
  1532. X  { fprintf (stderr,
  1533. X         "Error, write_sun can only handle 8 physical bits per pixel\n");
  1534. X    return (0);
  1535. X  }
  1536. X
  1537. X  if (image->hdr.physbits == 1 && (image->hdr.rowlen % 16) != 0)
  1538. X  { fprintf (stderr,
  1539. X    "Error, 1 bit deep files must have rowlen (%d) divisible by 16");
  1540. X    return (0);
  1541. X  }
  1542. X
  1543. X  if (image->hdr.physbits == 8 && image->hdr.bits == 1)
  1544. X    bits = 1;
  1545. X  else
  1546. X    bits = image->hdr.physbits > 1 ? 8 : 1;
  1547. X
  1548. X# ifdef DEBUG
  1549. X  fprintf (stderr, "write_sun: [%dx%d] rowlen %d, planes %d, bits %d, physbits %d, using %d\n",
  1550. X       image->hdr.cols,
  1551. X       image->hdr.rows,
  1552. X       image->hdr.rowlen,
  1553. X       image->hdr.planes,
  1554. X       image->hdr.bits,
  1555. X       image->hdr.physbits,
  1556. X           bits);
  1557. X# endif
  1558. X
  1559. X  width = image->hdr.cols;
  1560. X  height = image->hdr.rows;
  1561. X  rowlen = image->hdr.rowlen;
  1562. X  plnlen = image->hdr.plnlen;
  1563. X  clrlen = image->hdr.clrlen;
  1564. X  depth = bits * image->hdr.planes;
  1565. X
  1566. X  /* Initialize Sun raster header */
  1567. X  rhdr.ras_magic = SUN_MAGIC;
  1568. X  rhdr.ras_width = width;
  1569. X  rhdr.ras_height = height;
  1570. X  rhdr.ras_depth = depth;
  1571. X  rhdr.ras_length = plnlen * bits / 8;
  1572. X  rhdr.ras_type = RT_STANDARD;
  1573. X  rhdr.ras_maptype = depth > 8 ? RMT_RAW : clrlen ? RMT_EQUAL_RGB : RMT_NONE;
  1574. X  rhdr.ras_maplength = clrlen;
  1575. X
  1576. X  /* Write rasterfile header - note: use Sun byte order */
  1577. X  put_long (rhdr.ras_magic, wfile, BIG);
  1578. X  put_long (rhdr.ras_width, wfile, BIG);
  1579. X  put_long (rhdr.ras_height, wfile, BIG);
  1580. X  put_long (rhdr.ras_depth, wfile, BIG);
  1581. X  put_long (rhdr.ras_length, wfile, BIG);
  1582. X  put_long (rhdr.ras_type, wfile, BIG);
  1583. X  put_long (rhdr.ras_maptype, wfile, BIG);
  1584. X  put_long (rhdr.ras_maplength, wfile, BIG);
  1585. X  
  1586. X  /* Dump colormap if need be */
  1587. X  if (clrlen > 0)
  1588. X  { fwrite (image->cm, 1, clrlen, wfile); }
  1589. X  
  1590. X  /* Write bytes */
  1591. X  switch (depth)
  1592. X  { case 24:    rp = &image->bm[0];
  1593. X        gp = rp + plnlen;
  1594. X        bp = gp + plnlen;
  1595. X
  1596. X        for (i=0; i<plnlen; i++)
  1597. X        { fputc (*rp++, wfile);
  1598. X          fputc (*gp++, wfile);
  1599. X          fputc (*bp++, wfile);
  1600. X        }
  1601. X        break;
  1602. X
  1603. X    case 8:    fwrite (image->bm, 1, plnlen, wfile);
  1604. X        break;
  1605. X
  1606. X    case 1:    
  1607. X# ifdef DEBUG
  1608. X        fprintf (stderr, "Writing Sun 1bit file [%dx%d] rowlen %d\n",
  1609. X             width, height, rowlen);
  1610. X# endif
  1611. X        for (j=0; j<height; j++)
  1612. X        { bmp = &(image->bm[j*rowlen]);
  1613. X          byte = 0;
  1614. X
  1615. X          for (i=0; i<rowlen; i++)
  1616. X          { byte = (byte << 1) | (*bmp++ ? 0 : 1);
  1617. X
  1618. X            if ((i & 7) == 7)
  1619. X            { fputc (byte, wfile); byte = 0; }
  1620. X          }
  1621. X        }
  1622. X        break;
  1623. X
  1624. X    default:    fprintf  (stderr,
  1625. X                  "Error, write_sun given invalid depth %d bits\n",
  1626. X              depth);
  1627. X        return (0);
  1628. X  }
  1629. X  return (1);
  1630. X}
  1631. X
  1632. X/****************************************************************
  1633. X * read_sun (image, rfile)
  1634. X ****************************************************************/
  1635. X
  1636. Xread_sun (image, rfile, mstr, mlen)
  1637. XFBM *image;
  1638. XFILE *rfile;
  1639. Xchar *mstr;
  1640. Xint mlen;
  1641. X{ RASHDR rhdr;
  1642. X  int width, height, plnlen, rowlen, clrlen, res, depth;
  1643. X  register int i, j, byte;
  1644. X  register unsigned char *bmp, *rp, *gp, *bp;
  1645. X  int m1, m2, m3, m4;
  1646. X
  1647. X  m1 = NEXTMCH(rfile,mstr,mlen) & 0xff;
  1648. X  m2 = NEXTMCH(rfile,mstr,mlen) & 0xff;
  1649. X  m3 = NEXTMCH(rfile,mstr,mlen) & 0xff;
  1650. X  m4 = NEXTMCH(rfile,mstr,mlen) & 0xff;
  1651. X
  1652. X  rhdr.ras_magic = (m1 << 24) | (m2 << 16) | (m3 << 8)| (m4);
  1653. X
  1654. X  /* Write rasterfile header - note: use Sun byte order */
  1655. X  if (rhdr.ras_magic != SUN_MAGIC)
  1656. X  { fprintf (stderr, "Error, not a Sun raster file (bad magic %08x)\n",
  1657. X         rhdr.ras_magic);
  1658. X    return (0);
  1659. X  }
  1660. X
  1661. X  rhdr.ras_width = get_long (rfile, BIG);
  1662. X  rhdr.ras_height = get_long (rfile, BIG);
  1663. X  rhdr.ras_depth = get_long (rfile, BIG);
  1664. X  rhdr.ras_length = get_long (rfile, BIG);
  1665. X  rhdr.ras_type = get_long (rfile, BIG);
  1666. X  rhdr.ras_maptype = get_long (rfile, BIG);
  1667. X  rhdr.ras_maplength = get_long (rfile, BIG);
  1668. X
  1669. X  /* Check for nonstandard rasterfile formats */
  1670. X  if (rhdr.ras_type != RT_STANDARD)
  1671. X  { fprintf (stderr, "Error: rasterfile is not a Sun RT_STANDARD file\n");
  1672. X    return (0);
  1673. X  }
  1674. X
  1675. X  if (rhdr.ras_maplength > 0 && rhdr.ras_maptype != RMT_EQUAL_RGB)
  1676. X  { fprintf (stderr, "Error: color rasterfile is not RMT_EQUAL_RGB\n");
  1677. X    return (0);
  1678. X  }
  1679. X  
  1680. X  if (rhdr.ras_maplength == 0 &&
  1681. X      rhdr.ras_maptype != RMT_NONE &&
  1682. X      rhdr.ras_maptype != RMT_RAW)
  1683. X  { fprintf (stderr, "Error: black and white rasterfile is not RMT_NONE\n");
  1684. X    return (0);
  1685. X  }
  1686. X
  1687. X  if (rhdr.ras_depth != 24 && rhdr.ras_depth != 8 && rhdr.ras_depth != 1)
  1688. X  { fprintf (stderr, "Error, bits per pixel (%d) must be 1, 8 or 24\n", 
  1689. X         rhdr.ras_depth);
  1690. X    return (0);
  1691. X  }
  1692. X
  1693. X  /* Initialize and allocate input image */  
  1694. X  width = rhdr.ras_width;
  1695. X  height = rhdr.ras_height;
  1696. X  depth = rhdr.ras_depth;
  1697. X  clrlen = rhdr.ras_maplength;
  1698. X
  1699. X  if (depth == 1)
  1700. X  { rowlen = 16 * ((width + 15) / 16);
  1701. X    plnlen = rowlen * height;
  1702. X  }
  1703. X  else
  1704. X  { rowlen = width;
  1705. X    if (rowlen & 1) rowlen++;
  1706. X    
  1707. X    plnlen = width * height;
  1708. X  }
  1709. X  
  1710. X  /* Check for consitency between colormap and depth */
  1711. X  if (depth > 8 && clrlen > 0)
  1712. X  { fprintf (stderr,
  1713. X    "Error, input has colormap of length %d, but %d bits per pixel\n",
  1714. X    clrlen, depth);
  1715. X    return (0);
  1716. X  }
  1717. X
  1718. X  /* Initialize image header */
  1719. X  image->hdr.cols = width;
  1720. X  image->hdr.rows = height;
  1721. X  image->hdr.planes = (depth == 24) ? 3 : 1;
  1722. X  image->hdr.bits = (depth == 24) ? 8 : depth;
  1723. X  image->hdr.physbits = 8;
  1724. X  image->hdr.rowlen = rowlen;
  1725. X  image->hdr.plnlen = plnlen;
  1726. X  image->hdr.clrlen = clrlen;
  1727. X  image->hdr.aspect = 1.0;
  1728. X  image->hdr.title[0] = '\0';
  1729. X  image->hdr.credits[0] = '\0';
  1730. X
  1731. X  /* Allocate space */
  1732. X  alloc_fbm (image);
  1733. X
  1734. X  /* Read colormap if need be */
  1735. X  if (clrlen > 0 && (res = fread (image->cm, 1, clrlen, rfile)) != clrlen) 
  1736. X  { fprintf (stderr, "Error: couldn't read colormap, read %d of %d bytes\n",
  1737. X         res, clrlen);
  1738. X    return (0);
  1739. X  }
  1740. X
  1741. X  /* Read bytes */
  1742. X  switch (depth)
  1743. X  { case 24:    rp = &image->bm[0];
  1744. X        gp = rp + plnlen;
  1745. X        bp = gp + plnlen;
  1746. X
  1747. X        for (i=0; i<plnlen && !feof (rfile); i++)
  1748. X        { *rp++ = fgetc (rfile);
  1749. X          *gp++ = fgetc (rfile);
  1750. X          *bp++ = fgetc (rfile);
  1751. X        }
  1752. X        
  1753. X        if (i<plnlen)
  1754. X        { fprintf (stderr, "Error: %s %d of %d pixels (%d bytes)\n",
  1755. X               "EOF on bitmap after",
  1756. X               i, plnlen, plnlen * image->hdr.planes);
  1757. X          return (0);
  1758. X        }
  1759. X        
  1760. X        break;
  1761. X
  1762. X    case 8:    if ((res = fread (image->bm, 1, plnlen, rfile)) != plnlen)
  1763. X        { fprintf (stderr,
  1764. X               "Error: EOF on bitmap after %d of %d bytes\n",
  1765. X               res, plnlen);
  1766. X          return (0);
  1767. X        }
  1768. X        break;
  1769. X
  1770. X    case 1:    for (j=0; j<height; j++)
  1771. X        { bmp = &(image->bm[j * rowlen]);
  1772. X    
  1773. X          for (i=0; i<rowlen; i++)
  1774. X          { if ((i&7) == 0)
  1775. X            { if ((byte = fgetc (rfile)) == EOF)
  1776. X              { fprintf (stderr,
  1777. X                 "Error: EOF on bitmap after %d of %d bytes\n",
  1778. X                 j*rowlen + i, height*rowlen);
  1779. X            return (0);
  1780. X              }
  1781. X            }
  1782. X        
  1783. X            *bmp++ = (byte & 0x80) ? BLACK : WHITE;
  1784. X            byte <<= 1;
  1785. X          }
  1786. X        }
  1787. X        break;
  1788. X    default:    fprintf (stderr, "Invalid depth %d bits\n", depth);
  1789. X        return (0);
  1790. X  }
  1791. X
  1792. X  return (1);
  1793. X}
  1794. END_OF_FILE
  1795. if test 8735 -ne `wc -c <'flsun.c'`; then
  1796.     echo shar: \"'flsun.c'\" unpacked with wrong size!
  1797. fi
  1798. # end of 'flsun.c'
  1799. fi
  1800. if test -f 'pbm2ps.c' -a "${1}" != "-c" ; then 
  1801.   echo shar: Will not clobber existing file \"'pbm2ps.c'\"
  1802. else
  1803. echo shar: Extracting \"'pbm2ps.c'\" \(7263 characters\)
  1804. sed "s/^X//" >'pbm2ps.c' <<'END_OF_FILE'
  1805. X/*****************************************************************
  1806. X * pbm2ps.c: FBM Library 0.9 (Beta test) 07-Mar-89  Michael Mauldin
  1807. X *
  1808. X * Copyright (C) 1989 by Michael Mauldin.  Permission is granted to
  1809. X * use this file in whole or in part provided that you do not sell it
  1810. X * for profit and that this copyright notice is retained unchanged.
  1811. X *
  1812. X * pbm2ps.c: 
  1813. X *
  1814. X * USAGE
  1815. X *    % pbm2ps [ flags ] arguments
  1816. X *
  1817. X * BUGS
  1818. X *    Will blow up if the title has PostScript special characters
  1819. X *    in it (especially unbalanced parens)
  1820. X *
  1821. X * EDITLOG
  1822. X *    LastEditDate = Wed Mar  8 14:23:08 1989 - Michael Mauldin
  1823. X *    LastFileName = /usr2/mlm/src/misc/fbm/pbm2ps.c
  1824. X *
  1825. X * HISTORY
  1826. X * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
  1827. X *    Beta release (version 0.9) mlm@cs.cmu.edu
  1828. X *
  1829. X * 14-Sep-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  1830. X *    Created.
  1831. X *****************************************************************/
  1832. X
  1833. X# include <stdio.h>
  1834. X# include <ctype.h>
  1835. X
  1836. X# define MAXBAD 10
  1837. X
  1838. X# define USAGE "Usage: pbm2ps [ -s ] [ scale ] < pbm > postscript"
  1839. X
  1840. Xunsigned char    *bits;
  1841. Xint         w, h;
  1842. Xchar         title[80];
  1843. X
  1844. X/****************************************************************
  1845. X * main: Read a pbm format file and write it out as PostScript
  1846. X ****************************************************************/
  1847. X
  1848. X#ifndef lint
  1849. Xstatic char *fbmid =
  1850. X    "$FBM pbm2ps.c <0.9> 07-Mar-89  (C) 1989 by Michael Mauldin$";
  1851. X#endif
  1852. X
  1853. Xmain (argc, argv)
  1854. Xchar *argv[];
  1855. X{ int scale = -1, scribe = 0;
  1856. X
  1857. X  /* Get option */
  1858. X  while (--argc > 0 && (*++argv)[0] == '-')
  1859. X  { while (*++(*argv))
  1860. X    { switch (**argv)
  1861. X      { case 's':    scribe++; break;
  1862. X    default:    fprintf (stderr, USAGE);
  1863. X            exit (1);
  1864. X      }
  1865. X    }
  1866. X  }
  1867. X
  1868. X  if (argc > 0 && (scale = atoi (argv[0])) < 1)
  1869. X  { fprintf (stderr, USAGE); exit (1); }
  1870. X
  1871. X  if (read_pbm (stdin) && write_ps (scale, scribe)) exit (0);
  1872. X
  1873. X  exit (1);
  1874. X}
  1875. X
  1876. X/****************************************************************
  1877. X * read_pbm: Read a pbm bitmap into character array 'bits', setting
  1878. X *         width, height, and title
  1879. X ****************************************************************/
  1880. X
  1881. Xread_pbm (rfile)
  1882. XFILE *rfile;
  1883. X{ int ch;
  1884. X  register unsigned char *bmp, *tail;
  1885. X  int badcnt=0;
  1886. X
  1887. X  if ((ch = getc (rfile)) != 'P' || (ch = getc (rfile)) != '1')
  1888. X  { fprintf (stderr, "bad magic number, input not PBM file\n");
  1889. X    return (0);
  1890. X  }
  1891. X
  1892. X  title[0] = '\0';
  1893. X
  1894. X  if ((w = pbm_getint (stdin)) < 0 || (h = pbm_getint (stdin)) < 0)
  1895. X  { return (0); }
  1896. X
  1897. X  bits = (unsigned char *) malloc (w*h);
  1898. X  
  1899. X  bmp = bits;
  1900. X  tail = &bmp[h*w];
  1901. X  
  1902. X  /* Read bits, inverting so that 1=white and 0=black */
  1903. X  while (bmp < tail && (ch = getc (rfile)) != EOF)
  1904. X  { if (ch == '0') *bmp++ = 1;
  1905. X    else if (ch == '1') *bmp++ = 0;
  1906. X    else if (ch == '#') eatcomment ();
  1907. X    else if (isspace (ch)) /* ignore it */ ;
  1908. X    else if (++badcnt < MAXBAD)
  1909. X    { fprintf (stderr, "Ignoring junk character '%c'\n", ch); }
  1910. X    else
  1911. X    { fprintf (stderr, "Too many junk characters, bye!\n"); exit (1); }
  1912. X  }
  1913. X
  1914. X  if (ch == EOF)
  1915. X  { fprintf (stderr, "premature EOF, read %d of %d bits in [%dx%d]\n",
  1916. X        (bmp - bits), (tail - bits), w, h);
  1917. X    return (0);
  1918. X  }
  1919. X  
  1920. X  return (1);
  1921. X}
  1922. X
  1923. X/*****************************************************************
  1924. X * pbm_getint: Read a number from a PBM file, ignoring comments
  1925. X *****************************************************************/
  1926. X
  1927. Xpbm_getint (rfile)
  1928. XFILE *rfile;
  1929. X{ register int ch;
  1930. X  register int val = 0;
  1931. X
  1932. X  while ((ch = getc (rfile)) != EOF)
  1933. X  { if (ch == '#') eatcomment ();
  1934. X    else if (isspace (ch)) /* ignore it */ ;
  1935. X    else if (isdigit (ch)) break;
  1936. X    else
  1937. X    { fprintf (stderr, "Found junk character '%c' in header\n", ch);
  1938. X      return (-1);
  1939. X    }
  1940. X  }
  1941. X
  1942. X  while (isdigit (ch))
  1943. X  { val = val*10 + ch - '0';
  1944. X    ch = getc (rfile);
  1945. X  }
  1946. X  
  1947. X  return (val);
  1948. X}
  1949. X
  1950. X/*****************************************************************
  1951. X * eatcomment: Read comments and look for titles
  1952. X *****************************************************************/
  1953. X
  1954. Xeatcomment ()
  1955. X{ char cmtbuf[80];
  1956. X  register char *s;
  1957. X
  1958. X  /* Read rest of line, remove trailing newline and skip over leading spaces */
  1959. X  fgets (cmtbuf, sizeof (cmtbuf), stdin);
  1960. X  cmtbuf[strlen (cmtbuf) - 1] = '\0';
  1961. X  for (s=cmtbuf; isspace (*s); s++) ;
  1962. X
  1963. X  /* If the comment contains the title, squirrel it away */
  1964. X  if (!strncmp (s, "Title: ", 7)) strcpy (title, s+7);
  1965. X  fprintf (stderr, "Reading '%s'\n", title);
  1966. X}
  1967. X
  1968. X/****************************************************************
  1969. X * write_ps: Write out a 1 bit deep bitmap as a PostScript file
  1970. X *
  1971. X * Output is centered with at least 1" left margin, 1/2" right,
  1972. X * top and bottom margins.
  1973. X *
  1974. X * The title is printed in 14 pt Times-Bold centered at the top.
  1975. X * One half inch at the top is reserved for the title
  1976. X ****************************************************************/
  1977. X
  1978. X# define BYTESPERLINE 32
  1979. X# define PSRES 300    /* printer resolution, dots per inch */
  1980. X# define PPINCH 72    /* Points per inch */
  1981. X# define PAGW 8.5    /* page width 8.5 inches */
  1982. X# define PAGH 11.0    /* page height 11 inches */
  1983. X# define MAXW 7.0    /* maximum image width 7 inches */
  1984. X# define MAXH 9.5    /* maximum image height 9.5 inches */
  1985. X# define LMRG 1.0    /* left margin 1 inche */
  1986. X# define BMRG 0.5    /* bottom margin 1/2 inche */
  1987. X# define TMRG 0.125    /* Title margin, 1/8 inch */
  1988. X# define FSIZ 14    /* Font size for title (before scaling to 300 dpi) */
  1989. X
  1990. Xwrite_ps (scale, scribe)
  1991. Xint scale, scribe;
  1992. X{ register int x, y, k, byte, bytes=0;
  1993. X  register unsigned char *bmp = bits;
  1994. X  int dotsx, dotsy;
  1995. X  double pwidth, pheight, ctrx, ctry;
  1996. X
  1997. X  /* Pick the largest scale factor that makes the image fit */
  1998. X  if (scale < 1)
  1999. X  { dotsx = (int) MAXW * PSRES / w;
  2000. X    dotsy = (int) MAXH * PSRES / h;
  2001. X    scale = (dotsx < dotsy) ? dotsx : dotsy;
  2002. X    if (scale < 1) scale = 1;
  2003. X  }
  2004. X
  2005. X  fprintf (stderr, "pbm2ps: scale %d\n", scale);
  2006. X
  2007. X  /* Determine width and height of output in inches */  
  2008. X  pwidth = (double) w * scale;
  2009. X  pheight = (double) h * scale;
  2010. X  ctrx = ((double) MAXW / 2.0 + LMRG) * PSRES;
  2011. X  ctry = ((double) MAXH / 2.0 + BMRG) * PSRES;
  2012. X
  2013. X  printf ("%%%! %s\n\n", title[0] ? title : "PBM to PostScript");
  2014. X  printf ("%lg %lg scale\n", (double) PPINCH / PSRES, (double) PPINCH / PSRES);
  2015. X  if (title[0])
  2016. X  { printf ("/centershow { dup stringwidth pop");
  2017. X    printf (" 2 div 0 exch sub 0 rmoveto show } def\n");
  2018. X    printf ("/Times-Bold findfont %lg scalefont setfont\n",
  2019. X        (double) FSIZ * PSRES / PPINCH);
  2020. X    printf ("%lg %lg moveto\n",
  2021. X        ctrx, ctry + pheight / 2.0 + TMRG*PSRES);
  2022. X    printf ("(%s) centershow\n\n", title);
  2023. X  }
  2024. X
  2025. X  printf ("/picstr 32 string def\n");
  2026. X
  2027. X  if (!scribe)
  2028. X  { printf ("%lg %lg translate\n", ctrx - pwidth / 2, ctry - pheight / 2); }
  2029. X  printf ("%lg %lg scale\n", pwidth, pheight);
  2030. X  printf ("%d %d 1 [ %d 0 0 -%d 0 %d ] ", w, h, w, h, h);
  2031. X  printf ("{ currentfile picstr readhexstring pop }\n");
  2032. X  printf ("image\n");
  2033. X
  2034. X  for (y=0; y<h; y++)
  2035. X  { for (x=0; x<w; x += 8)
  2036. X    { byte = 0;
  2037. X      for (k=0; k<8; k++)
  2038. X      { byte = (byte << 1) | (((x+k) < w) ? *bmp++ : 0); }
  2039. X
  2040. X      printf ("%02x", byte);
  2041. X      if (++bytes % BYTESPERLINE == 0) printf ("\n");
  2042. X    }
  2043. X  }
  2044. X  
  2045. X  /* Pad so there are exactly BYTESPERLINE bytes in each line */
  2046. X  if (bytes % BYTESPERLINE)
  2047. X  { while (bytes++ % BYTESPERLINE) printf ("00");
  2048. X    printf ("\n");
  2049. X  }
  2050. X
  2051. X  if (!scribe) printf ("showpage\n");
  2052. X
  2053. X  return (1);  
  2054. X}
  2055. END_OF_FILE
  2056. if test 7263 -ne `wc -c <'pbm2ps.c'`; then
  2057.     echo shar: \"'pbm2ps.c'\" unpacked with wrong size!
  2058. fi
  2059. # end of 'pbm2ps.c'
  2060. fi
  2061. echo shar: End of archive 5 \(of 8\).
  2062. cp /dev/null ark5isdone
  2063. MISSING=""
  2064. for I in 1 2 3 4 5 6 7 8 ; do
  2065.     if test ! -f ark${I}isdone ; then
  2066.     MISSING="${MISSING} ${I}"
  2067.     fi
  2068. done
  2069. if test "${MISSING}" = "" ; then
  2070.     echo You have unpacked all 8 archives.
  2071.     rm -f ark[1-9]isdone
  2072. else
  2073.     echo You still need to unpack the following archives:
  2074.     echo "        " ${MISSING}
  2075. fi
  2076. ##  End of shell archive.
  2077. exit 0
  2078.